package web

import (
	"auth/server/web/middleware"
	"auth/server/web/v1"
	"github.com/asim/go-micro/plugins/registry/etcd/v4"
	"github.com/asim/go-micro/plugins/server/http/v4"
	httpCode "net/http"

	"time"

	"auth/config"
	"auth/utils"
	"github.com/gin-gonic/gin"
	"go-micro.dev/v4"
	"go-micro.dev/v4/registry"
	"go-micro.dev/v4/server"
)

var (
	routerRulesMap = map[string]bool{
		"/:name":                                                       true,
		"/:name/:name":                                                 true,
		"/:name/:name/:name":                                           true,
		"/:name/:name/:name/:name":                                     true,
		"/:name/:name/:name/:name/:name":                               true,
		"/:name/:name/:name/:name/:name/:name":                         true,
		"/:name/:name/:name/:name/:name/:name/:name":                   true,
		"/:name/:name/:name/:name/:name/:name/:name/:name":             true,
		"/:name/:name/:name/:name/:name/:name/:name/:name/:name":       true,
		"/:name/:name/:name/:name/:name/:name/:name/:name/:name/:name": true,
	}
)

var (
	webName           string
	webAddr           string
	defaultListenAddr = ":7771"
	srv               server.Server
)

func Init() micro.Option {
	webName = config.Conf.Name + "-http"

	if config.Conf.Http.HttpListen != "" {
		defaultListenAddr = config.Conf.Http.HttpListen
	}

	var opts = []server.Option{
		server.Name(webName),
		server.Version(config.Conf.Version),
		server.Address(defaultListenAddr),
		server.RegisterTTL(time.Second * 30),
		server.RegisterInterval(time.Second * 15),
	}

	if config.EtcdAddr != "" {
		opts = append(opts, server.Registry(etcd.NewRegistry(registry.Addrs(config.EtcdAddr))))
	}

	srv = http.NewServer(opts...)

	router := gin.New()
	gin.SetMode(gin.DebugMode)
	router.Use(gin.Logger())
	router.Use(gin.Recovery())

	// register routers
	v1Group := router.Group("api/v1/auth", middleware.OtelMiddleware(), middleware.SentinelMiddleware( // customize resource extractor if required
		// customize block fallback if required
		// abort with status 429 by default
		middleware.WithBlockFallback(func(ctx *gin.Context) {
			ctx.AbortWithStatusJSON(httpCode.StatusTooManyRequests, map[string]interface{}{
				"err":  "too many request; the quota used up",
				"code": httpCode.StatusTooManyRequests,
			})
		})))
	v1.Init(v1Group)

	utils.Throw(srv.Handle(srv.NewHandler(router)))
	if config.Conf.Traefik.Enabled {
		utils.Throw(config.Register(webName, srv))
	}

	middleware.InitWhiteUrlMap()
	return micro.Server(srv)
}
